#ifndef _RENDER_WINDOW_HPP
#define _RENDER_WINDOW_HPP

#include "Camera.hpp"
#include <functional>
#include <vector>
#include "vec2.hpp"
#include "Color.hpp"
#include "Mouse.hpp"

namespace phx
{

class RenderWindow
{
public:
	RenderWindow(GLint width, GLint height, char *title);
	bool isOpen();
	void display();
	void clear(const phx::Colorf &color = phx::Colorf::Gray);
	void close();
	void pollEvent();

	vec2f getSize();
	vec2f getPosition();
	void setKeyCallbackFunc(std::function<void(RenderWindow&, int, int, int, int)> func);
	void setMouseButtonCallbackFunc(std::function<void(RenderWindow&, ygg::Mouse::Button, ygg::Mouse::ButtonState)> func);
	void setFramerateLimit(GLint limit = 60);
	void setRenderCallbackFunc(std::function<void(RenderWindow&, unsigned int)> func);
	void useCamera(Camera &camera);
	
	bool isCursorVisible();
	void setCursorVisible(bool visible);

	friend class RenderingProcesser;
	friend struct CallbackInterface;
	friend class Cursor;
	~RenderWindow();
private:
	RenderWindow();
	RenderWindow(const RenderWindow&);
	void operator=(const RenderWindow&);
private:
	GLFWwindow *mGLFWwindow;
	GLint mWidth, mHeight;
	char *mTitle;
	std::function<void(RenderWindow&, int, int, int, int)> mKeyCallbackFunc;
	std::function<void(RenderWindow&, ygg::Mouse::Button, ygg::Mouse::ButtonState)> mMouseButtonCallbackFunc;
	std::function<void(RenderWindow&, unsigned int)> mRenderCallbackFunc;
	GLint mFramerateLimit;
	Camera *mCamera;
};

/*
// Callbacks
class KeyCallback
{
public:
	virtual void operator()(phx::RenderWindow &window, int key, int scancode, int action, int mods) = 0;
};

class SimpleKeyCallback : public KeyCallback
{
public:
	typedef void (*CallbackFunc)(phx::RenderWindow&, int, int, int, int);
	SimpleKeyCallback(CallbackFunc callbackFunc) : mCallbackFunc(callbackFunc){}
	virtual void operator()(phx::RenderWindow &window, int key, int scancode, int action, int mods){ mCallbackFunc(window, key, scancode, action, mods); }
private:
	CallbackFunc mCallbackFunc;
};

template <class T>
class ClassKeyCallback : public KeyCallback
{
public:
	template <class T>
	typedef void (T::*CallbackFunc)(phx::RenderWindow&, int, int, int, int);
	ClassKeyCallback(CallbackFunc callbackFunc, T instance) : mCallbackFunc(callbackFunc), mInstance(instance){}
	virtual void operator()(phx::RenderWindow &window, int key, int scancode, int action, int mods){ (mInstance->*mCallbackFunc)(window, key, scancode, action, mods); }
private:
	CallbackFunc mCallbackFunc;
	T mInstance;
};
*/

}

#endif